import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

// This class has been created in order to stress the application 
// so that we can detect consistency issues.
// Two classes are called. They share an integer sharedObject. The StressWrite class aims at 
// incrementing a counter until a certain value. The StressRead class aims at reading the 
// current number a certain number of times.

public class CompleteStress extends Thread {
	
	public static class StandardOutputThread extends Thread {
		
		private BufferedReader input;
		private String s;
	
			
		public StandardOutputThread(Process p, boolean errors) {
			super();
			if(!errors) {
				input = new BufferedReader(new InputStreamReader(p.getInputStream()));
			} else {
				input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
			}
		}
		
		public void run() {
			try {
				while((s = input.readLine()) != null)
					System.out.println(s);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	// The main method executes the main methods of 
	// StressRead and StressWrite in separate processes 
	// quite at the same time.
	
	public static void main(String argv[]) throws IOException, InterruptedException {
		
		if (argv.length < 1 || argv.length > 3) {
			System.out.println("java CompleteStress <nb iteration> [<nb writers> <nb readers>]");
			return;
		}
		int nb = Integer.parseInt(argv[0]);
		
		System.out.println("Beginning of the stress test");
		
		// Commands execution
		int nbWriters = (argv.length >= 2)? Integer.parseInt(argv[1]) : 1;
		int nbReaders = (argv.length == 3)? Integer.parseInt(argv[2]) : 1;
		
		List<Process> pw = new ArrayList<Process>();
		List<Process> pr = new ArrayList<Process>();
		
		for(int i=0; i<nbWriters; i++) {
			pw.add(Runtime.getRuntime().exec("java StressWrite "+nb));
			new StandardOutputThread(pw.get(i), false).start();
			new StandardOutputThread(pw.get(i), true).start();
			if(i==0) sleep(500);
		}
		
		for(int i=0; i<nbReaders; i++) {
			pr.add(Runtime.getRuntime().exec("java StressRead "+nb));
			new StandardOutputThread(pr.get(i), false).start();
			new StandardOutputThread(pr.get(i), true).start();
			if(i==0) sleep(500);
		}
		
		sleep(8000);
		for(int i=0; i<nbWriters; i++)
			pw.get(i).destroy();
		for(int i=0; i<nbReaders; i++)
			pr.get(i).destroy();
		
		System.out.println("Process destroyed");
		System.exit(0);
		
		
	}
	
}